package com.ls.server.service.model.impl;

import com.alibaba.fastjson.JSON;
import com.ls.server.domain.MCPEntity;
import com.ls.server.mcp.client.CustomMcpToolCallbackProvider;
import com.ls.server.service.model.ChatModelClient;
import com.ls.server.utils.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.ai.openai.OpenAiChatOptions;
import org.springframework.ai.openai.api.OpenAiApi;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * OpenAI 聊天模型客户端实现
 */
@Slf4j
public class OpenAIChatModelClient implements ChatModelClient {

    private String apiKey;
    private String apiUrl;

    private String model;

    private MCPEntity mcpEntitie;

    /**
     * 发送聊天请求（同步）
     *
     * @param prompt 提示词
     * @param options 选项
     * @return 回复内容
     */
    @Override
    public String chat(String prompt, Map<String, Object> options) {
        OpenAiChatModel chatModel = OpenAiChatModel.builder()
                .openAiApi(OpenAiApi.builder()
                        .apiKey(apiKey)
                        .baseUrl(apiUrl) // 使用传入的URL参数
                        .build())
                .defaultOptions(OpenAiChatOptions.builder()
                        .model(model)
                        .build())
                .build();
        var toolCallbackProviderBean = SpringContextUtil.getBean(CustomMcpToolCallbackProvider.class);
        ToolCallbackProvider[] toolCallbackProvider = toolCallbackProviderBean.getToolCallbackProvider(mcpEntitie);
        ChatClient.Builder builder = ChatClient.builder(chatModel)
                .defaultSystem("你好啊，今天又是美好一天。")
                .defaultTools(toolCallbackProvider);

        return builder.build().prompt(prompt).toolCallbacks(toolCallbackProvider).call().content();
    }

    /**
     * 发送聊天请求（异步流式）
     *
     * @param prompt 提示词
     * @param options 选项
     * @return 回复内容流
     */
    @Override
    public Flux<String> chatStream(String prompt, Map<String, Object> options) {
        // 实际实现需要使用WebClient等支持流式请求的客户端
        // 这里简化处理，将同步请求结果包装为Flux返回
        return Flux.just(chat(prompt, options));
    }

    /**
     * 获取模型名称
     *
     * @return 模型名称
     */
    @Override
    public String getModelName() {
        return "OpenAI";
    }

    /**
     * 初始化客户端
     *
     * @param apiKey API密钥
     * @param apiUrl API地址
     */
    @Override
    public void init(String apiKey, String apiUrl,String model) {
        this.apiKey = apiKey;
        this.apiUrl = apiUrl;
    }

    @Override
    public void init(String apiKey, String apiUrl, String model, MCPEntity mcpEntitie) {
        this.apiKey = apiKey;
        this.apiUrl = apiUrl;
        this.model = model;
        this.mcpEntitie = mcpEntitie;
    }

    /**
     * 构建请求体
     *
     * @param prompt 提示词
     * @param options 选项
     * @return 请求体
     */
    private Map<String, Object> buildRequestBody(String prompt, Map<String, Object> options) {
        Map<String, Object> requestBody = new HashMap<>();

        // 构建消息列表
        List<Map<String, String>> messages = new ArrayList<>();
        Map<String, String> message = new HashMap<>();
        message.put("role", "user");
        message.put("content", prompt);
        messages.add(message);

        requestBody.put("model", options.getOrDefault("model", "gpt-3.5-turbo"));
        requestBody.put("messages", messages);
        requestBody.put("temperature", options.getOrDefault("temperature", 0.7));
        requestBody.put("max_tokens", options.getOrDefault("max_tokens", 2000));

        // 合并其他选项
        if (options != null) {
            for (Map.Entry<String, Object> entry : options.entrySet()) {
                if (!requestBody.containsKey(entry.getKey())) {
                    requestBody.put(entry.getKey(), entry.getValue());
                }
            }
        }

        return requestBody;
    }

    /**
     * 提取响应内容
     *
     * @param responseMap 响应Map
     * @return 内容
     */
    private String extractContent(Map<String, Object> responseMap) {
        try {
            Map<String, Object> choices = (Map<String, Object>) ((List)responseMap.get("choices")).get(0);
            Map<String, Object> message = (Map<String, Object>) choices.get("message");
            return (String) message.get("content");
        } catch (Exception e) {
            log.error("解析OpenAI响应失败", e);
        }
        return "解析响应失败";
    }
}
